/*	$Id: start.S,v 1.1.1.1 2006/09/14 01:59:08 root Exp $ */

/*
 * Copyright (c) 2001 Opsycon AB  (www.opsycon.se)
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 * 1. Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 * 2. Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in the
 *    documentation and/or other materials provided with the distribution.
 * 3. All advertising materials mentioning features or use of this software
 *    must display the following acknowledgement:
 *	This product includes software developed by Opsycon AB, Sweden.
 * 4. The name of the author may not be used to endorse or promote products
 *    derived from this software without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS
 * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
 * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
 * SUCH DAMAGE.
 *
 */

#ifndef _KERNEL
#define _KERNEL
#endif

#include <asm.h>
#include <regnum.h>
#include <cpu.h>
#include <pte.h>

#include "pmon/dev/ns16550.h"
#include "target/prid.h"
#include "target/sbd.h"
#include "target/bonito.h"
#include "target/via686b.h"
#include "target/i8254.h"
#include "target/isapnpreg.h"
#include "target/ls2h.h"
#define DEBUG_LOCORE



#ifdef DEBUG_LOCORE
#define	TTYDBG(x) \
	.rdata;98: .asciz x; .text; la a0, 98b; bal stringserial; nop
#define	TTYDBG_COM1(x) \
	.rdata;98: .asciz x; .text; la a0, 98b; bal stringserial_COM1; nop
#else
#define TTYDBG(x)
#endif

#define	PRINTSTR(x) \
	.rdata;98: .asciz x; .text; la a0, 98b; bal stringserial; nop

#ifdef DEVBD2F_SM502
#define GPIOLED_DIR  0xe
#else
#define GPIOLED_DIR  0xf
#endif

#undef USE_GPIO_SERIAL
#ifndef USE_GPIO_SERIAL
#define GPIOLED_SET(x) \
	li v0,0xbfe0011c; \
lw v1,4(v0); \
or v1,0xf; \
xor v1,GPIOLED_DIR; \
sw v1,4(v0); \
li v1,(~x)&0xf;\
sw v1,0(v0);\
li v1,0x1000;\
78: \
subu v1,1;\
bnez v1,78b;\
nop;
#else
#define GPIOLED_SET(x)
#endif

/* Beep ON/OFF Function */
#define BEEP_ON \
	dli t1, 0x90000cfdfe00a080; \
	lbu t0, 0x0(t1); \
	or  t0, 0x4; \
	sb  t0, 0x0(t1); \
	nop; \
	nop;
#define BEEP_OFF \
	dli t1, 0x90000cfdfe00a080; \
	lbu t0, 0x0(t1); \
	and t0, 0xfb; \
	sb  t0, 0x0(t1); \
	nop; \
	nop;

/* set GPIO as output
 * x : 0x1<<offset
 */
#define GPIO_SET_OUTPUT(x) \
li		v0,		0xbfe0011c; \
lw		v1,		0(v0); \
or		v1,		x&0xffff; \
xor		v1,		0x0; \
sw		v1,		0(v0); \
lw		v1,		4(v0); \
or		v1,		x&0xffff; \
xor		v1,		x; \
sw		v1,		4(v0); \
nop; \
nop;

/* clear GPIO as output
 * x : 0x1 <<offsest
 */
#define GPIO_CLEAR_OUTPUT(x) \
li		v0,		0xbfe0011c; \
lw		v1,		0(v0); \
or		v1,		x&0xffff; \
xor		v1,		x; \
sw		v1,		0(v0); \
lw		v1,		4(v0); \
or		v1,		x&0xffff; \
xor		v1,		x; \
sw		v1,		4(v0); \
nop; \
nop;

/* WatchDog Close for chip MAX6369*/
#define WatchDog_Close \
li		v0,		0xbbef0000;\
li		v1,		0x00;\
sw		v1,		0x30(v0);\


/* WatchDog Enable for LS2H chip */
#define WatchDog_Enable \
li		v0,		0xbbef0000;\
li		v1,		0x02;\
sw		v1,		0x30(v0);\
li		v1,		0x1fffffff;\
sw		v1,		0x38(v0);\
li		v1,		0x01;\
sw		v1,		0x34(v0);\


#define w83627write(x,y,z) \
li		v0,		0xb800002e; \
li		v1,		0x87; \
sb		v1,		0(v0); \
sb		v1,		0(v0); \
li		v1,		0x7; \
sb		v1,		0(v0); \
li		v1,		x; \
sb		v1,		1(v0); \
li		v1,		y; \
sb		v1,		0(v0); \
li		v1,		z; \
sb		v1,		1(v0); \
li		v1,		0xaa; \
sb		v1,		0(v0); \
sb		v1,		0(v0); \
nop; \
nop 

#ifdef LS3A2H_STR
/* str need */
#define STR_XBAR_CONFIG_NODE_a0(OFFSET, BASE, MASK, MMAP) \
                        daddi   v0, t0, OFFSET;       \
                        dli     t1, BASE;             \
                        or      t1, t1, a0;           \
                        sd      t1, 0x00(v0);         \
                        dli     t1, MASK;             \
                        sd      t1, 0x40(v0);         \
                        dli     t1, MMAP;             \
                        sd      t1, 0x80(v0);        \
                                           nop


#endif

#define CONFIG_CACHE_64K_4WAY 1

#define tmpsize		s1
#define msize		s2
#define bonito		s4
#define dbg			s5
#define sdCfg		s6

#define CP0_CONFIG $16
#define CP0_TAGLO  $28
#define CP0_TAGHI  $29

/*
 * Coprocessor 0 register names
 */
#define CP0_INDEX $0
#define CP0_RANDOM $1
#define CP0_ENTRYLO0 $2
#define CP0_ENTRYLO1 $3
#define CP0_CONF $3
#define CP0_CONTEXT $4
#define CP0_PAGEMASK $5
#define CP0_WIRED $6
#define CP0_INFO $7
#define CP0_BADVADDR $8
#define CP0_COUNT $9
#define CP0_ENTRYHI $10
#define CP0_COMPARE $11
#define CP0_STATUS $12
#define CP0_CAUSE $13
#define CP0_EPC $14
#define CP0_PRID $15
#define CP0_CONFIG $16
#define CP0_LLADDR $17
#define CP0_WATCHLO $18
#define CP0_WATCHHI $19
#define CP0_XCONTEXT $20
#define CP0_FRAMEMASK $21
#define CP0_DIAGNOSTIC $22
#define CP0_PERFORMANCE $25
#define CP0_ECC $26
#define CP0_CACHEERR $27
#define CP0_TAGLO $28
#define CP0_TAGHI $29
#define CP0_ERROREPC $30

#define CP0_DEBUG  $23
#define CP0_DEPC   $24
#define CP0_DESAVE $31

/*
 *   Register usage:
 *
 *	s0	link versus load offset, used to relocate absolute adresses.
 *	s1	free
 *	s2	memory size.
 *	s3	free.
 *	s4	Bonito base address.
 *	s5	dbg.
 *	s6	sdCfg.
 *	s7	rasave.
 *	s8	L3 Cache size.
 */


.set	noreorder
.globl	_start
.globl	start
.globl	__main
_start:
start:
.globl	stack
stack = start - 0x4000		/* Place PMON stack below PMON start in RAM */

/* NOTE!! Not more that 16 instructions here!!! Right now it's FULL! */
    mtc0	zero, COP_0_STATUS_REG
    mtc0	zero, COP_0_CAUSE_REG
    li	t0, SR_BOOT_EXC_VEC	/* Exception to Boostrap Location */
    mtc0	t0, COP_0_STATUS_REG
    la	sp, stack
    la	gp, _gp

//	bal	uncached		/* Switch to uncached address space */
	nop
//GPIOLED_SET(2)
	
	/* WatchDog chip MAX6369 disable work */
//	WatchDog_Close

	bal	locate			/* Get current execute address */
	nop

	uncached:
	or	ra, UNCACHED_MEMORY_ADDR
	j	ra
	nop

	/*
	 *  Reboot vector usable from outside pmon.
	 */
	.align	8
ext_map_and_reboot:
	bal	CPU_TLBClear
	nop

	li	a0, 0xc0000000
	li	a1, 0x40000000
	bal	CPU_TLBInit
	nop
	la	v0, tgt_reboot
	la	v1, start
	subu	v0, v1
	lui	v1, 0xffc0
	addu	v0, v1
	jr	v0
	nop

	/*
	 *  Exception vectors here for rom, before we are up and running. Catch
	 *  whatever comes up before we have a fully fledged exception handler.
	 */
	.align	9			/* bfc00200 */
	la	a0, v200_msg
	bal	stringserial
	nop
	b	exc_common

	.align	7			/* bfc00280 */
	la	a0, v280_msg
	bal	stringserial
	nop
	b	exc_common

	/* Cache error */
	.align	8			/* bfc00300 */
	PRINTSTR("\r\nPANIC! Unexpected Cache Error exception! ")
	mfc0	a0, COP_0_CACHE_ERR
	bal	hexserial
	nop
	b	exc_common

	/* General exception */
	.align	7			/* bfc00380 */
	la	a0, v380_msg
	bal	stringserial
	nop
	b	exc_common

	.align	8			/* bfc00400 */
	la	a0, v400_msg
	bal	stringserial
	nop

#if 1
	b	exc_common
	nop

#ifdef LS3A2H_STR
/* 
 * 3A2H STR config start 
 */

	.align  8           /* suspend addr: bfc00500 */
	.set 	mips64
	/* Enable DDR control register */

	dli	t0, 0x900000000faaa040
	sd	a0, 0x0(t0) //store ra

	dli	t1, 0x900000000faaa048
	sd	a1, 0x0(t1) //store sp

	dli	t2, 0x900000000faaa050
	dli	t0, 0x5a5a5a5a5a5a5a5a
	sd	t0, 0x0(t2) //store str flag

	lui	t0, 0xbfe0
	lw	t1, 0x0180(t0)
	nop
	li	t2, ~(0x1 << 8)
	and	t1, t1, t2
	sw	t1, 0x0180(t0)
	sync

	/* set MC0 Enter refresh mode */
	li	a0,0x0
	dli	t0, 0x900000003ff00000
	STR_XBAR_CONFIG_NODE_a0(0x10, \
		0x0000000000000000, \
		0xfffffffff0000000, \
		0x00000000000000f0)

	dli	a0, 0x900000000ff00000
	ld	t1, 0x30(a0)
	dli	t3, (0x1 << 32)
	or	t1, t1, t3
	sd	t1, 0x30(a0)
	sync

	/* set MC1 Enter refresh mode */
	li	a0,0x0
	dli	t0, 0x900000003ff00000
	STR_XBAR_CONFIG_NODE_a0(0x10, \
		0x0000000000000000, \
		0xfffffffff0000000, \
		0x00000000000000f1)

	dli	a0, 0x900000000ff00000
	ld	t1, 0x30(a0)
	dli	t3, (0x1 << 32)
	or	t1, t1, t3
	sd	t1, 0x30(a0)
	sync

	//enfo ec: I want to come into str,please keep RESET# hight
again:
	//PRINTSTR("\r\nWrite EC GPIO41 start... ")
	lui	t1, 0xbbf0
	li	t6, 0x100000
1:
	lb	t2, 0x66(t1)
	li	t3, 2
	and	t2, t2, t3
	subu	t6,0x1
	beqz	t6,again
	nop
	bnez	t2, 1b
	nop
	li	t2, 0x4e
	sb	t2, 0x66(t1)
	sync
	nop
	nop
	nop
	li	t6, 0x100000
2:
	lb	t2, 0x66(t1)
	li	t3, 2
	and	t2, t2, t3
	subu	t6,0x1
	beqz	t6,2b
	nop
	bnez	t2, 2b
	nop
	li	t2, 0xff
	sb	t2, 0x62(t1)
	sync
	nop

	/* start of set ACPI reg on 2H */
	li	t0, 0xbbef0000

	/* set key,usb wakeup of reg GPE0_EN */
	lw	t1, 0x2c(t0)
	li	t3, (0x1 << 8)|(0x3f<<10)
	or	t1, t1, t3
	sw	t1, 0x2c(t0)

	/* clear 0-15 of reg GPE0_STS */
	lw	t1, 0x28(t0)
	li	t3, 0x0000ffff
	sw	t3, 0x28(t0)

	/* clear 0-15 of reg PM1_STS */
	lw	t1, 0x0c(t0)
	li	t3, 0x0000ffff
	sw	t3, 0x0c(t0)

	/* set reg PM1_CNT to get into S3*/
	lw	t1, 0x14(t0)
	li	t3, 0x00003400
	sw	t3, 0x14(t0)

/* end of set ACPI reg on 2H */
 
1:
	b  1b
	nop
 
	.set 	mips3
//////////////////////////////////////////

#else
	/* Debug exception */
	.align  7           /* bfc00480 */
#endif
	#include "exc_ejtag.S"
#endif

	exc_common:
	.set 	mips64
	mfc0	t0, $15, 1
	.set 	mips3
	PRINTSTR("\r\nCPU ID=")
	move	a0, t0
	bal	hexserial
	nop
	PRINTSTR("\r\nCAUSE=")
	mfc0	a0, COP_0_CAUSE_REG
	bal	hexserial
	nop
	PRINTSTR("\r\nSTATUS=")
	mfc0	a0, COP_0_STATUS_REG
	bal	hexserial
	nop
	PRINTSTR("\r\nERRORPC=")
	mfc0	a0, COP_0_ERROR_PC
	bal	hexserial
	nop
	PRINTSTR("\r\nEPC=")
	mfc0	a0, COP_0_EXC_PC
	bal	hexserial
	nop
1:
	b 1b
	nop
#ifndef ROM_EXCEPTION
	PRINTSTR("\r\nDERR0=")
	cfc0	a0, COP_0_DERR_0
	bal	hexserial
	nop
	PRINTSTR("\r\nDERR1=")
	cfc0	a0, COP_0_DERR_1
	bal	hexserial
	nop
#else
1:
	b 1b
	nop
#endif

	//	b	ext_map_and_reboot
	nop

	.align 8
	nop
	.align 8
	.word read
	.word write
	.word open
	.word close
	.word nullfunction
	.word printf
	.word vsprintf
	.word nullfunction
	.word nullfunction
	.word getenv
	.word nullfunction
	.word nullfunction
	.word nullfunction
	.word nullfunction


	/*
	 *  We get here from executing a bal to get the PC value of the current execute
	 *  location into ra. Check to see if we run from ROM or if this is ramloaded.
	 */
	locate:
	la	s0,start
	subu	s0,ra,s0
	and	s0,0xffff0000

	li	    t0,SR_BOOT_EXC_VEC
	mtc0	t0,COP_0_STATUS_REG
	mtc0    zero,COP_0_CAUSE_REG
	.set noreorder

    li	bonito,PHYS_TO_UNCACHED(BONITO_REG_BASE)

//Open 64-bit address space
    mfc0    t0, CP0_STATUS
    li      t1, 0x00e0
	or      t0, t0, t1
	mtc0    t0, CP0_STATUS


		.set 	mips64
		mfc0	t0, $15, 1
		.set 	mips3
		andi	t0, 0x3ff

#if 1 /* clear Mail BOX */
#define CORE0_BUF0 0x900000003ff01020
#define CORE1_BUF0 0x900000003ff01120
#define CORE2_BUF0 0x900000003ff01220
#define CORE3_BUF0 0x900000003ff01320
#define FN_OFF 0x020
#define SP_OFF 0x028
#define GP_OFF 0x030
#define A1_OFF 0x038
#define SYSTEM_INIT_OK  0x5a5a

		dli     t1, CORE0_BUF0
		andi    t3, t0, 0x3  //local cpuid
		dsll    t3, 8
		or      t1, t1, t3

		andi    t4, t0, 0xc  //node id
		dsll    t4, 42
		or      t1, t1, t4

		sd      $0, 0x0(t1)
		sd      $0, 0x8(t1)
		sd      $0, 0x10(t1)
		sd      $0, 0x18(t1)
#endif
		li      a0, 0x0
		bne     t0, a0, slave_main
		nop

		bal	initserial
		nop
		bal	initserial_uart1
		nop

		//#define DEBUG_LS3
#ifdef DEBUG_LS3
		dli     a0, 0xfff
		and     t1, t1, a0
		dsll    t1, t1, 10
		1:
		bnez    t1, 1b
		daddi   t1, t1, -1


		PRINTSTR("CP0_STATUS:")
		mfc0    a0, CP0_STATUS
		bal	    hexserial
		nop
		PRINTSTR("\r\n\r\n")


		sync
		sync
		nop
		nop
		nop
		nop
		nop
		nop
		nop
		nop
		nop
		nop
		nop
		nop
		nop
		nop
		nop
		nop
		nop
		nop
		nop
		nop
		nop
		nop
		nop
		nop
		nop
		nop
		PRINTSTR("sync ok\r\n")
		nop
		nop
		nop
		nop
		nop
		nop
		nop
		nop
		nop
		nop
		nop
		nop
		nop
		nop
		nop
		nop
		nop
		nop
		nop
		nop
		nop
		nop
		nop
		nop
		nop
		nop
		nop
		nop
		nop
		1:
		bnez    t0, 1b
		nop
#endif

#ifdef DEBUG_LS3
		dli     t2, 0x9800000000000000
		cache   21, 0x0(t2)
		PRINTSTR("Hit WB Invalidate_D 0 \r\n")
		dli     t2, 0x9800000000000020
		cache   21, 0x0(t2)
		PRINTSTR("Hit WB Invalidate_D 2 \r\n")
		dli     t2, 0x9800000000000040
		cache   21, 0x0(t2)
		PRINTSTR("Hit WB Invalidate_D 4 \r\n")
		dli     t2, 0x9800000000000060
		cache   21, 0x0(t2)
		PRINTSTR("Hit WB Invalidate_D 6 \r\n")

		dli     t2, 0x9800000000000000
		ld      a0, 0x0(t2)
		PRINTSTR("Read 0 \r\n")
		dli     t2, 0x9800000000000020
		ld      a0, 0x0(t2)
		PRINTSTR("Read 2 \r\n")
		dli     t2, 0x9800000000000040
		ld      a0, 0x0(t2)
		PRINTSTR("Read 4 \r\n")
		dli     t2, 0x9800000000000060
		ld      a0, 0x0(t2)
		PRINTSTR("Read 6 \r\n")

		dli     t1, 0x9800000000000000
		dli     t2, 0x9800000000400000
		1:
		ld      a0, 0x0(t1)
		daddiu  t1, t1, 0x20
		bne     t1, t2, 1b
		nop
		PRINTSTR("Scache scan done \r\n")

		1:
		b       1b
		nop

#endif


#if 0
		PRINTSTR("Shut down other cores\r\n")
		li      a0, 0xbfe00180
		lw      a1, 0x0(a0)
		li      t1, 0xffff1fff
		and     a1, a1, t1
		sw      a1, 0x0(a0)

#endif

		dli      a0,0x900000001ff00080
		li      t0,0x99
		sb      t0,0x0(a0)

#ifdef LS3_HT
		b       core0_start
		nop
#endif

#define MOD_MASK	0x00000003
#define MOD_B		0x00000000 /* byte "modifier" */
#define MOD_H		0x00000001 /* halfword "modifier" */
#define MOD_W		0x00000002 /* word "modifier" */
#if __mips64
#define MOD_D		0x00000003 /* doubleword "modifier" */
#endif

#define OP_MASK		0x000000fc
#define	OP_EXIT		0x00000000 /* exit (status) */
#define OP_DELAY	0x00000008 /* delay (cycles) */
#define OP_RD		0x00000010 /* read (addr) */
#define OP_WR		0x00000014 /* write (addr, val) */
#define OP_RMW		0x00000018 /* read-modify-write (addr, and, or) */
#define OP_WAIT		0x00000020 /* wait (addr, mask, value) */

#define WR_INIT(mod,addr,val) \
		.word	OP_WR|mod,PHYS_TO_UNCACHED(addr);\
		.word	(val),0

#define RD_INIT(mod,addr) \
		.word	OP_RD|mod,PHYS_TO_UNCACHED(addr);\
		.word	0,0

#define RMW_INIT(mod,addr,and,or) \
		.word	OP_RMW|mod,PHYS_TO_UNCACHED(addr);\
		.word	(and),(or)

#define WAIT_INIT(mod,addr,and,or) \
		.word	OP_WAIT|mod,PHYS_TO_UNCACHED(addr);\
		.word	(mask),(val)

#define DELAY_INIT(cycles) \
		.word	OP_DELAY,(cycles);\
		.word	0,0

#define EXIT_INIT(status) \
		.word	OP_EXIT,(status);\
		.word	0,0

#define BONITO_INIT(r,v) WR_INIT(MOD_W,BONITO_BASE+/**/r,v)
#define BONITO_BIS(r,b) RMW_INIT(MOD_W,BONITO_BASE+(r),~0,b)
#define BONITO_BIC(r,b) RMW_INIT(MOD_W,BONITO_BASE+(r),~(b),0)
#define BONITO_RMW(r,c,s) RMW_INIT(MOD_W,BONITO_BASE+(r),~(c),s)

#define CFGADDR(idsel,function,reg) ((1<<(11+(idsel)))+((function)<<8)+(reg))
#define _ISABWR_INIT(mod,function,isabreg,val) \
		WR_INIT(MOD_W,BONITO_BASE+BONITO_PCIMAP_CFG,CFGADDR(PCI_IDSEL_VIA686B,function,isabreg)>>16) ; \
		RD_INIT(MOD_W,BONITO_BASE+BONITO_PCIMAP_CFG) ; \
		WR_INIT(mod,PCI_CFG_SPACE+(CFGADDR(PCI_IDSEL_VIA686B,function,isabreg)&0xffff),val)

#define _ISABRD_INIT(mod,function,isabreg) \
		WR_INIT(MOD_W,BONITO_BASE+BONITO_PCIMAP_CFG,CFGADDR(PCI_IDSEL_VIA686B,function,isabreg)>>16) ; \
		RD_INIT(MOD_W,BONITO_BASE+BONITO_PCIMAP_CFG) ; \
		RD_INIT(mod,PCI_CFG_SPACE+(CFGADDR(PCI_IDSEL_VIA686B,function,isabreg)&0xffff))


#define _ISAWR_INIT(isareg,val) \
		WR_INIT(MOD_B,PCI_IO_SPACE+(isareg),val)

#define _ISARD_INIT(isareg) \
		RD_INIT(MOD_B,PCI_IO_SPACE+(isareg))


#define ISABBWR_INIT(function,isabreg,val) \
		_ISABWR_INIT(MOD_B,function,(isabreg),val)
#define ISABHWR_INIT(function,isabreg,val) \
		_ISABWR_INIT(MOD_H,function,(isabreg),val)
#define ISABWWR_INIT(function,isabreg,val) \
		_ISABWR_INIT(MOD_W,function,isabreg,val)
#define ISAWR_INIT(isareg,val) \
		_ISAWR_INIT(isareg,val)
#define ISARD_INIT(isareg) \
		_ISARD_INIT(isareg)
	//	GPIOLED_SET(4)

		bal	1f
		nop

		/* bonito endianess */
		BONITO_BIC(BONITO_BONPONCFG,BONITO_BONPONCFG_CPUBIGEND)
		BONITO_BIC(BONITO_BONGENCFG,BONITO_BONGENCFG_BYTESWAP|BONITO_BONGENCFG_MSTRBYTESWAP)
		BONITO_BIS(BONITO_BONPONCFG, BONITO_BONPONCFG_IS_ARBITER)

		/*
		 * In certain situations it is possible for the Bonito ASIC
		 * to come up with the PCI registers uninitialised, so do them here
		 */
#define PCI_CLASS_BRIDGE		0x06
#define PCI_CLASS_SHIFT			24
#define PCI_SUBCLASS_BRIDGE_HOST	0x00
#define PCI_SUBCLASS_SHIFT		16
#define PCI_COMMAND_IO_ENABLE		0x00000001
#define PCI_COMMAND_MEM_ENABLE		0x00000002
#define PCI_COMMAND_MASTER_ENABLE	0x00000004
#define PCI_COMMAND_STATUS_REG		0x04
#define PCI_MAP_IO			0X00000001
#define PCI_CFG_SPACE			BONITO_PCICFG_BASE

		BONITO_INIT(BONITO_PCICLASS,(PCI_CLASS_BRIDGE << PCI_CLASS_SHIFT) | (PCI_SUBCLASS_BRIDGE_HOST << PCI_SUBCLASS_SHIFT))
		BONITO_INIT(BONITO_PCICMD, BONITO_PCICMD_PERR_CLR|BONITO_PCICMD_SERR_CLR|BONITO_PCICMD_MABORT_CLR|BONITO_PCICMD_MTABORT_CLR|BONITO_PCICMD_TABORT_CLR|BONITO_PCICMD_MPERR_CLR)
		//BONITO_INIT(BONITO_PCILTIMER, 0)
		BONITO_INIT(BONITO_PCILTIMER, 255)
		BONITO_INIT(BONITO_PCIBASE0, 0)
		BONITO_INIT(BONITO_PCIBASE1, 0)
		BONITO_INIT(BONITO_PCIBASE2, 0)
		BONITO_INIT(BONITO_PCIEXPRBASE, 0)
		BONITO_INIT(BONITO_PCIINT, 0)

		BONITO_INIT(0x150,0x8000000c)
		BONITO_INIT(0x154,0xffffffff)

		BONITO_BIS(BONITO_PCICMD, BONITO_PCICMD_PERRRESPEN)

		BONITO_BIS(BONITO_PCICMD, PCI_COMMAND_IO_ENABLE|PCI_COMMAND_MEM_ENABLE|PCI_COMMAND_MASTER_ENABLE)

		BONITO_BIC(BONITO_BONGENCFG, 0x80)

#BONITO_BIS(BONITO_BONGENCFG, BONITO_BONGENCFG_BUSERREN)

		/* Set debug mode */
		BONITO_BIS(BONITO_BONGENCFG, BONITO_BONGENCFG_DEBUGMODE)

		/******** added to init southbridge*/

#if  (PCI_IDSEL_VIA686B != 0)
		/* Set the SMB base address */
		ISABWWR_INIT(4, SMBUS_IO_BASE_ADDR, SMBUS_IO_BASE_VALUE | 0x1)
		/* enable the host controller */
		ISABHWR_INIT(4, SMBUS_HOST_CONFIG_ADDR, SMBUS_HOST_CONFIG_ENABLE_BIT)
		/* enable the SMB IO ports */
		ISABBWR_INIT(4, PCI_COMMAND_STATUS_REG, PCI_COMMAND_IO_ENABLE)

		/* 15us ISA bus refresh clock */
#define ISAREFRESH (PT_CRYSTAL/(1000000/15))
		ISARD_INIT(CTC_PORT+PT_CONTROL)

		/* program i8254 ISA refresh counter */
		ISAWR_INIT(CTC_PORT+PT_CONTROL,PTCW_SC(PT_REFRESH)|PTCW_16B|PTCW_MODE(MODE_RG))
		ISAWR_INIT(CTC_PORT+PT_REFRESH, ISAREFRESH & 0xff)
		ISAWR_INIT(CTC_PORT+PT_REFRESH, ISAREFRESH >> 8)
#endif

		EXIT_INIT(0)


#define	Init_Op	0
#define	Init_A0	4
#define	Init_A1	8
#define	Init_A2	12
#define	Init_Size	16

		1:	move a0,ra
		reginit:			/* local name */
		lw	t3, Init_Op(a0)
		lw	t0, Init_A0(a0)
		and	t4,t3,OP_MASK


		/*
		 * EXIT(STATUS)
		 */
		bne	t4, OP_EXIT, 8f
		nop
		move	v0,t0
		b	.done
		nop

		/*
		 * DELAY(CYCLES)
		 */
		8:	bne	t4, OP_DELAY, 8f
		nop
		1:	/////bnez	t0,1b
		subu	t0,1
		b	.next
		nop
		/*
		 * READ(ADDR)
		 */
		8:	bne	t4,OP_RD,8f
		nop
		and	t4,t3,MOD_MASK

		bne	t4,MOD_B,1f
		nop
		lbu	t5,0(t0)
		b	.next
		nop
		1:	bne	t4,MOD_H,1f
		nop
		lhu	t5,0(t0)
		b	.next
		nop
		1:	bne	t4,MOD_W,1f
		nop
#if __mips64
		lwu	t5,0(t0)
#else
		lw	t5,0(t0)
#endif
		b	.next
		nop
		1:
#if __mips64
		lw	t5,0(t0)
		b	.next
		nop
#else
		b	.fatal
		nop
#endif

		/*
		 * WRITE(ADDR,VAL)
		 */
		8:	bne	t4,OP_WR,8f
		nop
		lw	t1,Init_A1(a0)
		and	t4,t3,MOD_MASK

		bne	t4,MOD_B,1f
		nop
		sb	t1,0(t0)
		b	.next
		nop
		1:	bne	t4,MOD_H,1f
		nop
		sh	t1,0(t0)
		b	.next
		nop
		1:	bne	t4,MOD_W,1f
		nop
		sw	t1,0(t0)
		b	.next
		nop

		1:
#if __mips64
		sd	t1,0(t0)
		b	.next
		nop
#else
		b	.fatal
		nop
#endif


		/*
		 * RMW(ADDR,AND,OR)
		 */
		8:	bne	t4,OP_RMW,8f
		nop
		lw	t1,Init_A1(a0)
		lw	t2,Init_A2(a0)
		and	t4,t3,MOD_MASK

		bne	t4,MOD_B,1f
		nop
		lbu	t4,0(t0)
		and	t4,t1
		or	t4,t2
		sb	t4,0(t0)
		b	.next
		nop
		1:	bne	t4,MOD_H,1f
		nop
		lhu	t4,0(t0)
		and	t4,t1
		or	t4,t2
		sh	t4,0(t0)
		b	.next
		nop
		1:	bne	t4,MOD_W,1f
		nop
		lw	t4,0(t0)
		and	t4,t1
		or	t4,t2
		sw	t4,0(t0)
		b	.next
		nop

		1:
#if __mips64
		ld	t4,0(t0)
		and	t4,t1
		or	t4,t2
		sd	t4,0(t0)
		b	.next
		nop
#else
		b	.fatal
		nop
#endif


		/*
		 * WAIT(ADDR,MASK,VAL)
		 */
		8:	bne	t4,OP_WAIT,8f
		nop
		lw	t1,Init_A1(a0)
		lw	t2,Init_A2(a0)
		and	t4,t3,MOD_MASK

		bne	t4,MOD_B,1f
		nop
		3:	lbu	t4,0(t0)
		and	t4,t1
		bne	t4,t2,3b
		nop
		b	.next
		nop
		1:	bne	t4,MOD_H,1f
		nop
		3:	lhu	t4,0(t0)
		and	t4,t1
		bne	t4,t2,3b
		nop
		b	.next
		nop
		1:	bne	t4,MOD_W,1f
		nop
		3:	lw	t4,0(t0)
		and	t4,t1
		bne	t4,t2,3b
		nop
		b	.next
		nop
		1:
#if __mips64
3:	ld	t4,0(t0)
	and	t4,t1
	bne	t4,t2,3b
	nop
	b	.next
	nop
#else
	b	.fatal
	nop
#endif


	.next:	addu	a0,Init_Size
	b	reginit	
	nop	

	8:
	.fatal:	b .done
	nop
	bal 	stuck
	nop
	.done:	

	/*
	   GPIOLED_SET(5)
	   bal 	superio_init
	   nop

	   GPIOLED_SET(6)
	   bal	initserial
	   nop
	   GPIOLED_SET(7)
	 */

	core0_start:
	PRINTSTR("\r\nPMON2000 MIPS Initializing. Standby...\r\n")
	/*
	   PRINTSTR("ERRORPC=")
	   mfc0	a0, COP_0_ERROR_PC
	   bal	hexserial
	   nop

	   PRINTSTR(" CONFIG=")
	   mfc0	a0, COP_0_CONFIG
	   bal	hexserial
	   nop
	   PRINTSTR("\r\n")

	   PRINTSTR(" PRID=")
	   mfc0	a0, COP_0_PRID
	   bal	hexserial
	   nop
	   PRINTSTR("\r\n")
	 */

	bnez s0,1f
	nop

	li a0,128
	la v0,initmips
	jr v0
	nop
	1:

	/* 
	 * Now determine DRAM configuration and size by
	 * reading the I2C EEROM on the DIMMS
	 */

##############################################

	/* 
	 * now, we just write ddr2 parameters directly. 
	 * we should use i2c for memory auto detecting. 
	 */
gs_2f_v3_ddr2_cfg:

	//Read sys_clk_sel
#if 1
	TTYDBG ("\r\n0xbfe00190  : ")
	li  t2,0xbfe00190
	ld  t1, 0x0(t2)
	dsrl a0, t1, 32
	bal hexserial
	nop
	move    a0, t1
	bal hexserial
	nop
	TTYDBG ("\r\nCPU CLK SEL : ")
	dsrl t1, t1, 32
	andi a0, t1, 0x1f
	bal hexserial
	nop


	TTYDBG ("\r\nCPU clk frequency = SYSCLK x 0x")
	andi  t0, t1, 0x1f
	li  a0, 0x1f
	bne t0, a0, 1f
	nop
	TTYDBG ("1\r\n")
	b   2f
	nop
	1:
	andi    t0, t1, 0x1f
	andi    a0, t0, 0xf
	addi    a0, a0, 0x1e
	bal     hexserial
	nop
	TTYDBG (" / ")
	srl     a0, t0, 4
	beqz    a0, 3f
	nop
	TTYDBG (" 2\r\n")
	b       2f
	3:        
	nop
	TTYDBG (" 1\r\n")
	2:      
	TTYDBG ("MEM CLK SEL : ")
	dsrl t0, t1, 5
	andi a0, t0, 0x1f
	bal hexserial
	nop

	TTYDBG ("\r\nDDR clk frequency = MEMCLK x 0x")
	dsrl t0, t1, 5
	andi    t0, t0, 0x1f
	li  a0, 0x1f
	bne t0, a0, 1f
	nop
	TTYDBG ("1\r\n")
	b   2f
	nop
	1:
	dsrl t0, t1, 5
	andi t0, t0, 0x1f
	andi    a0, t0, 0xf
	addi    a0, a0, 0x1e
	bal     hexserial
	nop
	TTYDBG (" / ")
	srl     a0, t0, 4
	beqz    a0, 3f
	nop
	TTYDBG (" 4\r\n")
	b       2f
	nop
	3:
	TTYDBG (" 3\r\n")
	2:      
#endif    

##########################################

#include "loongson3_fixup.S"

##########################################
#ifdef LS3_HT
		WatchDog_Enable;
//#include "loongson3_HT_init.S" // for no ls2h cpu on board
		WatchDog_Close;
#endif

//#include "3aserver_bridge_config.S"	// for no ls2h cpu on board

//        bal     tgt_testchar
//        nop  
//        bnez    v0, after_ht
        nop  


#include "loongson3_HT_init_2h.S" // for no ls2h cpu on board
##########################################
after_ht:

		/* enable power led */

		// for no ls2h cpu on board 
#ifdef LOONGSON_3A2H

//begin :Beep on -> delay -> Beep off
	bal	beep_on
	nop
	li	a0,0x800
	1:
	addiu	a0,-1
	nop
	bnez	a0,1b
	nop
	bal	beep_off
	nop
//end

//		bal	 enable_lpcio_dev8  /* enable Super IO config port 2e-2h, 4e-4f */  
//		nop
#endif

//configure DDR freq by software
#if 1
    li      t5, 0x17
#if 0
    PRINTSTR("Please input DDR frequency SELLECT[4:0](default: 0x1e;0x1f: skip software setting):\r\n");
    dli     t6, 0x00
    bal     inputaddress #input value stored in v0
    nop
    dli     t6, 0x1f
    and     v0, v0, t6
    beq     v0, t6, 88f
    nop
    move    t5, v0
#endif

    TTYDBG  ("\r\nSet DDR frequency by software\r\n")
    move    a2, $0
    bal     config_mc_frequency
    nop

88:
#endif



		bal CPU_TLBClear
		nop
		/*
		 *  Reset and initialize caches to a known state.
		 */

		and	t1, t3, 0x10
		addu	s6, t1, 16		/* s6 = D cache line size */
		TTYDBG("Init tlb...\r\n")
		bal     tlb_init
		nop
#if 1 /* TLB init */
	    TTYDBG("Init htpcitlb...\r\n")
	
	/* WatchDog chip MAX6369 disable work */
	WatchDog_Close

#include "pcitlb.S"
#endif
		//TTYDBG("Init caches...\r\n")

#if 1
		//mfc0    a0, COP_0_PRID
		//li      a1, 0x6301
		//bne     a0,a1,1f
		//nop
		TTYDBG("godson2 caches found\r\n")
		bal     godson2_cache_init
		nop
		TTYDBG("scache init node 0\r\n")
		dli a0, 0x9800000000000000
		bal	scache_init_64 // whd
		nop
#endif

#if 1
		PRINTSTR("Jump to 9fc\r\n")
		lui     t0, 0xdfff
		ori     t0, t0, 0xffff
		bal     1f
		nop
		1:
		and     ra, ra, t0
		addiu   ra, ra, 16
		jr      ra
		nop

#endif

#if 1
		mfc0   $4, $16
		and    $4,0xfffffff8
		or     $4,0x3
		mtc0   $4,$16

		TTYDBG("cache enable done\r\n")
#endif

#if 1 
	    dli     t0, CORE0_BUF0 #buf of cpu0
        li      a1, SYSTEM_INIT_OK
	    sw      a1, 0x0(t0)
	    nop
#endif

//##########################################
//DDR config start
//cxk
####################################
#include "ddr_dir/ddr_param_define.h"
#include "ddr_dir/ddr_config_define.h"
#define DISABLE_DIMM_ECC
#define PRINT_MSG
#ifndef ARB_LEVEL
//#define FIX_DDR_PARAM
#endif
#ifdef  ARB_LEVEL
#define AUTO_ARB_LEVEL
#endif
#ifdef  AUTO_ARB_LEVEL
#define CHECK_ARB_LEVEL_FREQ
#ifdef  AUTO_DDR_CONFIG
#define CHECK_ARB_LEVEL_DIMM
#endif
//#define DEBUG_AUTO_ARB_LEVEL
#endif
//#define DEBUG_DDR
//#define DEBUG_DDR_PARAM

    TTYDBG("\r\nStart Init Memory, wait a while......\r\n")
####################################
    move    msize, $0
    move    s3, $0
//!!!!important--s1 must be correctly set

    TTYDBG("NODE 0 MEMORY CONFIG BEGIN\r\n")

#ifdef  AUTO_DDR_CONFIG
        dli     s1, 0x32170000  //set use MC1 or MC0 or MC1/0 and give All device id
#else
        dli     s1, 0xc1e10200c1e10204  //set use MC1 or MC0 or MC1/0 and give All DIMM infor // danmian
        dli     s1, 0xc1e30400c1e30404  //set use MC1 or MC0 or MC1/0 and give All DIMM infor // shuagnmian
        dli     s1, 0xc1ec0400c1ec0404  //set use MC1 or MC0 or MC1/0 and give All DIMM infor // shuagnmian
        dli     s1, 0xc0a10408c0a10408  //dian mian 2GB
        dli     s1, 0xc0a18404 
#endif
#include "ddr_dir/loongson3_ddr2_config.S"

    TTYDBG("Init Memory done.\r\n")

/*judge the node0 whether have memory*/
    and     a0, msize, 0xff
    beqz    a0, beep_on
    nop

##########################################
#ifdef  DEBUG_DDR
#if 1
    PRINTSTR("\r\nDo test?(0xf: skip): ")
    bal     inputaddress
    nop
    and     v0, v0, 0xf
    dli     a1, 0x1
    bgt     v0, a1, 3f
    nop
#endif

    dli     s1, 0x0010000080000000  //NODE 0, start from 0x80000000
#if 1
    PRINTSTR("\r\ndefault s1 = 0x");
    dsrl    a0, s1, 32
    bal     hexserial
    nop
    PRINTSTR("__")
    move    a0, s1
    bal     hexserial
    nop
    PRINTSTR("\r\nChange test param s1(0: skip)?: ")
    bal     inputaddress
    nop
    beqz    v0, 1f
    nop
    move    s1, v0
1:
#endif
1:
    dli     t1, 0x0010
    bal     test_mem
    nop
    move    t1, v0
    PRINTSTR("\r\n")
    dsrl    a0, t1, 32
    bal     hexserial
    nop
    move    a0, t1
    bal     hexserial
    nop
    beqz    t1, 2f
    nop
    PRINTSTR("  Error found!!\r\n")
2:
#if 0
    b       1b
    nop
#endif

3:
#endif

#ifdef  AUTO_ARB_LEVEL
#include "ddr_dir/store_auto_arb_level_info.S"
#endif
#########################################

#if 0 //cww_X2
		w83627write(0x8,0x30,0x1)
		w83627write(0x8,0xf5,0x40)
		w83627write(0x7,0x2d,0x1)
		w83627write(0x9,0xf3,0x0)

		PRINTSTR("\r\n======X1 core0 map windows:\r\n")
		li      t1, 23
		dli     t2, 0x900000003ff02000
		1:
		move	a0, t2
		bal	hexserial64
		nop
		PRINTSTR(": ")

		ld      a0, 0x0(t2)
		bal	hexserial64
		nop
		PRINTSTR("\r\n")

		daddiu  t2, t2, 8
		bnez    t1, 1b
		addiu   t1, t1, -1

		PRINTSTR("\r\n======X2 cpu map windows:\r\n")
		li      t1, 23
		dli     t2, 0x900000003ff00000
		1:
		move	a0, t2
		bal	hexserial64
		nop
		PRINTSTR(": ")

		ld      a0, 0x0(t2)
		bal	hexserial64
		nop
		PRINTSTR("\r\n")

		daddiu  t2, t2, 8
		bnez    t1, 1b
		addiu   t1, t1, -1

		PRINTSTR("\r\n======X2 pci map windows:\r\n")
		li      t1, 23
		dli     t2, 0x900000003ff00100
		1:
		move	a0, t2
		bal	hexserial64
		nop
		PRINTSTR(": ")

		ld      a0, 0x0(t2)
		bal	hexserial64
		nop
		PRINTSTR("\r\n")

		daddiu  t2, t2, 8
		bnez    t1, 1b
		addiu   t1, t1, -1
#endif

#if 0
		PRINTSTR("\r\n======read HT config reg:\r\n")
		dli     t2, 0x90000efdfb000000

		move	a0, t2
		bal	hexserial64
		nop
		PRINTSTR(": ")

		ld      a0, 0x0(t2)
		bal	hexserial64
		nop
		PRINTSTR("\r\n")

		daddiu	a0, t2, 0x60
		bal	hexserial64
		nop
		PRINTSTR(": ")

		ld      a0, 0x60(t2)
		bal	hexserial64
		nop
		PRINTSTR("\r\n")

		daddiu	a0, t2, 0x68
		bal	hexserial64
		nop
		PRINTSTR(": ")

		ld      a0, 0x68(t2)
		bal	hexserial64
		nop
		PRINTSTR("\r\n")

		daddiu	a0, t2, 0x70
		bal	hexserial64
		nop
		PRINTSTR(": ")

		ld      a0, 0x70(t2)
		bal	hexserial64
		nop
		PRINTSTR("\r\n")
#endif

//#include "loongson3_showwindows.S"

##########################################

#include "machine/newtest/newdebug.S"

##########################################

		bootnow:
#ifdef AUTO_DDR_CONFIG  // for no ls2h cpu on board, disable AUTO_DDR_CONFIG
		bal spd_info_store
		nop
#endif
		
		TTYDBG("Copy PMON to execute location...\r\n")
#ifdef DEBUG_LOCORE
		TTYDBG("  start = 0x")
		la	a0, start
		bal	hexserial
		nop
		TTYDBG("\r\n  s0 = 0x")
		move	a0, s0
		bal	hexserial
		nop
		TTYDBG("\r\n")
#endif
		la	a0, start
		li	a1, 0xbfc00000
		la	a2, _edata
		subu	t1, a2, a0
		srl	t1, t1, 2

		move	t0, a0
		move	t1, a1
		move	t2, a2

		/* copy text section */

		1:	and	t3,t0,0x0000ffff
		bnez	t3,2f
		nop
		move	a0,t0
		bal	hexserial
		nop
		li	a0,'\r'
		bal 	tgt_putchar
		nop
		2:	lw	t3, 0(t1)
		nop
		sw	t3, 0(t0)
		addu	t0, 4
		addu	t1, 4
		bne	t2, t0, 1b
		nop

		PRINTSTR("\ncopy text section done.\r\n")

		/* Clear BSS */
		la	a0, _edata
		la	a2, _end
		2:	sw	zero, 0(a0)
		bne	a2, a0, 2b
		addu	a0, 4


		TTYDBG("Copy PMON to execute location done.\r\n")

		TTYDBG("sp=");
	    move a0, sp
		bal	hexserial
		nop
		PRINTSTR("\r\n")

		li	a0, 4096*1024
		sw	a0, CpuTertiaryCacheSize /* Set L3 cache size */

		/* pass pointer to kseg1 tgt_putchar */
		la  a1, tgt_putchar
		addu a1,a1,s0

		la  a2, stringserial
		addu a2,a2,s0

		move	a0,msize
		la	v0, initmips
		jalr	v0
		nop
		stuck:
#ifdef DEBUG_LOCORE
		TTYDBG("Dumping GT64240 setup.\r\n")
		TTYDBG("offset----data------------------------.\r\n")
		li	s3, 0
		1:
		move	a0, s3
		bal	hexserial
		nop
		TTYDBG(": ")
		2:
		add	a0, s3, bonito
		lw	a0, 0(a0)
		bal	hexserial
		addiu	s3, 4
		TTYDBG(" ")
		li	a0, 0xfff
		and	a0, s3
		beqz	a0, 3f
		li	a0, 0x01f
		and	a0, s3
		bnez	a0, 2b
		TTYDBG("\r\n")
		b	1b
		nop
		3:
		b	3b
		nop

#else
		b	stuck
		nop
#endif
		/*
		 *  Clear the TLB. Normally called from start.S.
		 */
#if __mips64
#define MTC0 dmtc0
#else 
#define MTC0 mtc0
#endif
		LEAF(CPU_TLBClear)
		li	a3, 0			# First TLB index.

		li	a2, PG_SIZE_4K
		MTC0   a2, COP_0_TLB_PG_MASK   # Whatever...

		1:
		MTC0   zero, COP_0_TLB_HI	# Clear entry high.
		MTC0   zero, COP_0_TLB_LO0	# Clear entry low0.
		MTC0   zero, COP_0_TLB_LO1	# Clear entry low1.

		mtc0    a3, COP_0_TLB_INDEX	# Set the index.
		addiu	a3, 1
		li	a2, 64
		nop
		nop
		tlbwi				# Write the TLB

		bne	a3, a2, 1b
		nop

		jr	ra
		nop
		END(CPU_TLBClear)

		/*
		 *  Set up the TLB. Normally called from start.S.
		 */
		LEAF(CPU_TLBInit)
		li	a3, 0			# First TLB index.

		li	a2, PG_SIZE_16M
		MTC0   a2, COP_0_TLB_PG_MASK   # All pages are 16Mb.

		1:
		and	a2, a0, PG_SVPN
		MTC0   a2, COP_0_TLB_HI	# Set up entry high.

		move	a2, a0
		srl	a2, a0, PG_SHIFT 
		and	a2, a2, PG_FRAME
		ori	a2, PG_IOPAGE
		MTC0   a2, COP_0_TLB_LO0	# Set up entry low0.
		addu	a2, (0x01000000 >> PG_SHIFT)
		MTC0   a2, COP_0_TLB_LO1	# Set up entry low1.

		mtc0    a3, COP_0_TLB_INDEX	# Set the index.
		addiu	a3, 1
		li	a2, 0x02000000
		subu	a1, a2
		nop
		tlbwi				# Write the TLB

		bgtz	a1, 1b
		addu	a0, a2			# Step address 32Mb.

		jr	ra
		nop
		END(CPU_TLBInit)
		
		LEAF(spd_info_store)
                 move    t8,ra

                 TTYDBG("\r\n spd_info_store begain.\r\n")

                 dli    t5, 0xffffffff8fffa000;

                 dli    t7, 0xa1;
                 dli    t6, 0xa9; //slot1 slot2 slot3       

         4:
                 move    a0, t7
		 bne     a0, 0xa1, 5f
		 nop 
		 dli     a0, 0xaf; //slot0
         5:        dli     a1, 0x2;
                 //GET_I2C_NODE_ID_a2
                 bal     i2cread;
                 nop;

                 dli     t3, 0x80
                 bltu    v0, t3, 2f
                 nop;
                 move    t3, t5;
                 daddiu  t3, 0x100;
                 move    t4, t5;
        1:
                 sb      zero,0(t4);
                 daddiu  t4, 0x1;
                 bltu    t4, t3, 1b
                 nop;

                         b       3f
                  nop;

        2:
                move    t4, t5;
                dli     t0, 0x0; //used as counter
        1:
                move    a0, t7;
		bne     a0, 0xa1, 6f
		nop
	        dli     a0, 0xaf
        6:      move    a1, t0;
                //GET_I2C_NODE_ID_a2
                 bal     i2cread;
                 nop;

                sb      v0, 0(t4);

                dli     a1, 0x100
                daddiu  t4, 0x1;
                daddiu  t0, 0x1;
                bne     t0, a1, 1b;
                nop
        3:
                daddiu  t5, 0x100;
                daddiu  t7, 0x2;

                bltu    t7, t6, 4b
                nop
		
		

                TTYDBG("\r\n spd_info_store done.\r\n")

                 jr      t8
                 nop
                 END(spd_info_store)
		LEAF(stringserial)
		move	a2, ra
#ifdef ROM_EXCEPTION
		li a1,0x3ec00000
		addu	a1, a0, a1
#else
		addu	a1, a0, s0
#endif
		lbu	a0, 0(a1)
		1:
		beqz	a0, 2f
		nop
		bal	tgt_putchar
		addiu	a1, 1
		b	1b
		lbu	a0, 0(a1)

		2:
		j	a2
		nop
		END(stringserial)

		LEAF(outstring)
		move	a2, ra
		move	a1, a0
		lbu	a0, 0(a1)
		1:
		beqz	a0, 2f
		nop
		bal	tgt_putchar
		addiu	a1, 1
		b	1b
		lbu	a0, 0(a1)

		2:
		j	a2
		nop
		END(outstring)

		LEAF(hexserial)
		move	a2, ra
		move	a1, a0
		li	a3, 7
		1:
		rol	a0, a1, 4
		move	a1, a0
		and	a0, 0xf
#ifdef ROM_EXCEPTION
		la	v0, (hexchar+0x3ec00000)
#else
		la	v0, hexchar
		addu	v0, s0
#endif
		addu	v0, a0
		bal	tgt_putchar
		lbu	a0, 0(v0)

		bnez	a3, 1b
		addu	a3, -1

		j	a2
		nop
		END(hexserial)
		//#define USE_LPC_UART # defined in pmon_cfg
#ifdef USE_LPC_UART
		LEAF(tgt_putchar)
#	la	v0, COM1_BASE_ADDR
		la	v0, COM3_BASE_ADDR
		1:
		lbu	v1, NSREG(NS16550_LSR)(v0)
		and	v1, LSR_TXRDY
#	li	v1, 1
		beqz	v1, 1b
		nop

		sb	a0, NSREG(NS16550_DATA)(v0)
		move	v1, v0
#	la	v0, COM1_BASE_ADDR
		la	v0, COM3_BASE_ADDR
		bne	v0, v1, 1b
		nop

		j	ra
		nop	
		END(tgt_putchar)
#else

		LEAF(tgt_putchar)
		la	v0,GS3_UART_BASE 
		1:
		lbu	v1, NSREG(NS16550_LSR)(v0)
		and	v1, LSR_TXRDY
#	li	v1, 1
		beqz	v1, 1b
		nop
		sb	a0, NSREG(NS16550_DATA)(v0)
		move	v1, v0
		la	v0, GS3_UART_BASE
		bne	v0, v1, 1b
		nop
		la	v0,GS3_UART1_BASE 
		1:
		lbu	v1, NSREG(NS16550_LSR)(v0)
		and	v1, LSR_TXRDY
#	li	v1, 1
		beqz	v1, 1b
		nop
		sb	a0, NSREG(NS16550_DATA)(v0)
		move	v1, v0
		la	v0, GS3_UART1_BASE
		bne	v0, v1, 1b
		nop
		j	ra
		nop	
		END(tgt_putchar)
#endif
		LEAF(beep_on)
		jr ra
		nop

		/* enable gpio0 output */
		//li	t1,0xbbd000c4
		dli	t1,0x90000e001fd000c4
		lh	t0,0(t1)
		and	t0,0xfffe
		sh	t0,0(t1)
		/* set gpio0 high */
		//li	t1,0xbbd000cc
		dli	t1,0x90000e001fd000cc
		lh	t0,0(t1)
		or	t0,0x0001
		sh	t0,0(t1)

		nop
		jr	ra
		nop
		END(beep_on)

		LEAF(beep_off)
		jr ra
		nop

		/* enable gpio0 output */
		//li	t1,0xbbd000c4
		dli	t1,0x90000e001fd000c4
		lh	t0,0(t1)
		and	t0,0xfffe
		sh	t0,0(t1)
		/* set gpio0 low */
		//li	t1,0xbbd000cc
		dli	t1,0x90000e001fd000cc
		lh	t0,0(t1)
		and	t0,0xfffe
		sh	t0,0(t1)

		jr	ra
		nop
		END(beep_off)
		/* baud rate definitions, matching include/termios.h */
#define B0      0
#define B50     50      
#define B75     75
#define B110    110
#define B134    134
#define B150    150
#define B200    200
#define B300    300
#define B600    600
#define B1200   1200
#define B1800   1800
#define B2400   2400
#define B4800   4800
#define B9600   9600
#define B19200  19200
#define B38400  38400
#define B57600  57600
#define B115200 115200


#ifdef USE_LPC_UART
		LEAF(initserial)
#	la	v0, COM1_BASE_ADDR
		la	v0, COM3_BASE_ADDR
		1:
#set UART FIFO
		li	v1, FIFO_ENABLE|FIFO_RCV_RST|FIFO_XMT_RST|FIFO_TRIGGER_4
		sb	v1, NSREG(NS16550_FIFO)(v0)

#set THR/RDR to BRDL mode
		li	v1, CFCR_DLAB                  #DLAB
		sb	v1, NSREG(NS16550_CFCR)(v0)    

#if 0
		1:
		li      v1, 0x78
		sb	v1, 0x7 (v0)    

#        li      v1,12
#        li      a0,0xbff00080
#        sb      v1,0x0(a0)

		lb	v1, 0x7 (v0)    
		lb	v1, 0x7 (v0)    
#       li      a0,0xbff00080
#        sb      v1,0x0(a0)
		b 1b
#endif

#set Baud rate low byte
		li	v1, NS16550HZ/(16*CONS_BAUD)   #set BRDL
		sb	v1, NSREG(NS16550_DATA)(v0)

#set Baud rate high byte
		srl	v1, 8
		sb	v1, NSREG(NS16550_IER)(v0)     #set BRDH

#set word length to 8bit
		li	v1, CFCR_8BITS                 #8bit
		sb	v1, NSREG(NS16550_CFCR)(v0)

#set DTR and RTS valid
		li	v1, MCR_DTR|MCR_RTS
		sb	v1, NSREG(NS16550_MCR)(v0)

#disable all interrupt
		li	v1, 0x0
		sb	v1, NSREG(NS16550_IER)(v0)

		move	v1, v0
#	la	v0, COM1_BASE_ADDR
		la	v0, COM3_BASE_ADDR
		bne	v0, v1, 1b
		nop

		j	ra
		nop
		END(initserial)
#else
		LEAF(initserial)
		li  a0, GS3_UART_BASE

		li	t1,128
#	addiu	a2,a0,3
		sb	t1,3(a0)
#ifdef	BONITO_33M 
		li	t1,0x12      # divider, highest possible baud rate,for 33M crystal
#else
#ifdef BONITO_25M 
		li	t1,0x0e      # divider, highest possible baud rate,for 25M crystal
#else
#ifdef BONITO_50M 
		li	t1,0x1b      # divider, highest possible baud rate,for 50M crystal
#endif
#endif
#endif
		sb	t1,0(a0)
		li	t1,0x0     # divider, highest possible baud rate
		sb	t1,1(a0)
		li	t1,3
		sb	t1,3(a0)

#srl	t1,t1,0x8
		li	t1,0
		sb	t1,1(a0)
#li	t1,1      # divider, highest possible baud rate


		li	t1,71
		sb	t1,2(a0)
		jr	ra
		nop
		END(initserial)
#endif

		LEAF(initserial_uart1)
		li  a0, GS3_UART1_BASE

		li	t1,128
#	addiu	a2,a0,3
		sb	t1,3(a0)
#ifdef	BONITO_33M 
		li	t1,0x12      # divider, highest possible baud rate,for 33M crystal
#else
#ifdef BONITO_25M 
		li	t1,0x0e      # divider, highest possible baud rate,for 25M crystal
#else
#ifdef BONITO_50M 
		li	t1,0x1b      # divider, highest possible baud rate,for 50M crystal
#endif
#endif
#endif
		sb	t1,0(a0)
		li	t1,0x0     # divider, highest possible baud rate
		sb	t1,1(a0)
		li	t1,3
		sb	t1,3(a0)

#srl	t1,t1,0x8
		li	t1,0
		sb	t1,1(a0)
#li	t1,1      # divider, highest possible baud rate


		li	t1,71
		sb	t1,2(a0)
		jr	ra
		nop
		END(initserial_uart1)

		LEAF(initserial_COM1)
		la	v0, COM1_BASE_ADDR
#la	v0, 0xba0003f8
		1:
#set UART FIFO
		li	v1, FIFO_ENABLE|FIFO_RCV_RST|FIFO_XMT_RST|FIFO_TRIGGER_4
		sb	v1, NSREG(NS16550_FIFO)(v0)

#set THR/RDR to BRDL mode
		li	v1, CFCR_DLAB                  #DLAB
		sb	v1, NSREG(NS16550_CFCR)(v0)    


#set Baud rate low byte
		li	v1, NS16550HZ/(16*CONS_BAUD)   #set BRDL
		//li	v1, 1843200/(16*CONS_BAUD)   #set BRDL
		sb	v1, NSREG(NS16550_DATA)(v0)

#set Baud rate high byte
		srl	v1, 8
		sb	v1, NSREG(NS16550_IER)(v0)     #set BRDH

#set word length to 8bit
		li	v1, CFCR_8BITS                 #8bit
		sb	v1, NSREG(NS16550_CFCR)(v0)

#set DTR and RTS valid
		li	v1, MCR_DTR|MCR_RTS
		sb	v1, NSREG(NS16550_MCR)(v0)

#disable all interrupt
		li	v1, 0x0
		sb	v1, NSREG(NS16550_IER)(v0)

		move	v1, v0
		la	v0, COM1_BASE_ADDR
#la	v0, 0xba0002f8
		bne	v0, v1, 1b
		nop

		j	ra
		nop
		END(initserial_COM1)
		LEAF(stringserial_COM1)
		move	a2, ra
		addu	a1, a0, s0
		lbu	a0, 0(a1)
		1:
		beqz	a0, 2f
		nop
		bal	tgt_putchar_COM1
		addiu	a1, 1
		b	1b
		lbu	a0, 0(a1)

		2:
		j	a2
		nop
		END(stringserial_COM1)
		LEAF(hexserial_COM1)
		move	a2, ra
		move	a1, a0
		li	a3, 7
		1:
		rol	a0, a1, 4
		move	a1, a0
		and	a0, 0xf
		la	v0, hexchar
		addu	v0, s0
		addu	v0, a0
		bal	tgt_putchar_COM1
		lbu	a0, 0(v0)

		bnez	a3, 1b
		addu	a3, -1

		j	a2
		nop
		END(hexserial_COM1)

		LEAF(tgt_putchar_COM1)
		la	v0, COM1_BASE_ADDR
#la	v0, 0xba0002f8
		1:
		lbu	v1, NSREG(NS16550_LSR)(v0)
		and	v1, LSR_TXRDY
#	li	v1, 1
		beqz	v1, 1b
		nop

		sb	a0, NSREG(NS16550_DATA)(v0)
		move	v1, v0
		la	v0, COM1_BASE_ADDR
#la	v0, 0xba0002f8
		bne	v0, v1, 1b
		nop

		j	ra
		nop	
		END(tgt_putchar_COM1)


#include "i2c.S"
#ifdef AUTO_DDR_CONFIG  // for no ls2h cpu on board, disable AUTO_DDR_CONFIG
#include "ddr_dir/detect_node_dimm.S"
#endif

		__main:
		j	ra
		nop


		.rdata
		transmit_pat_msg:
		.asciz	"\r\nInvalid transmit pattern.  Must be DDDD or DDxDDx\r\n"
		v200_msg:
		.asciz	"\r\nPANIC! Unexpected TLB refill exception!\r\n"
		v280_msg:
		.asciz	"\r\nPANIC! Unexpected XTLB refill exception!\r\n"
		v380_msg:
		.asciz	"\r\nPANIC! Unexpected General exception!\r\n"
		v400_msg:
		.asciz	"\r\nPANIC! Unexpected Interrupt exception!\r\n"
		hexchar:
		.ascii	"0123456789abcdef"

		.text
		.align	2
		/*
		 *   I2C Functions used in early startup code to get SPD info from
		 *   SDRAM modules. This code must be entirely PIC and RAM independent.
		 */

		/* Delay macro */
#define	DELAY(count)	\
		li v0, count;	\
		99:			\
		bnz	vo, 99b;\
		addiu	v0, -1


#define I2C_INT_ENABLE	0x80
#define I2C_ENABLE	0x40
#define I2C_ACK		0x04
#define I2C_INT_FLAG	0x08
#define I2C_STOP_BIT	0x10
#define I2C_START_BIT	0x20

#define	I2C_AMOD_RD	0x01

#define	BUS_ERROR				0x00
#define	START_CONDITION_TRA			0x08
#define	RSTART_CONDITION_TRA			0x10
#define	ADDR_AND_WRITE_BIT_TRA_ACK_REC		0x18
#define	ADDR_AND_READ_BIT_TRA_ACK_REC		0x40
#define	SLAVE_REC_WRITE_DATA_ACK_TRA		0x28
#define	MAS_REC_READ_DATA_ACK_NOT_TRA		0x58

#define Index_Store_Tag_D			0x09
#define Index_Invalidate_I			0x00
#define Index_Writeback_Inv_D			0x01
#define Index_Store_Tag_S			0x0b
#define Index_Writeback_Inv_S			0x03

		LEAF(nullfunction)
		jr ra
		nop
		END(nullfunction)

#define CP0_ECC  $26
		LEAF(scache_init)
#        daddi   sp, sp, 0xfff8
#        sd      ra, 0(sp)
		move	t7, ra
#if 0 /* gx 2G */
		.word 0x40028001 #mfc0    v0,c0_config1
		and     v0, 0xf 
		beqz    v0, 1f  
		nop     
		jr      ra      
		nop     
		1:
#endif

		lui     a0, 0x8000
		lui     a2, 0x0010      #4M/4way
#lui     a2, 0x0002      #512k/4way
#lui     a2, 0x0004      #1M/4way
		scache_init_4way:
#a0=0x80000000, a2=scache_size
#a3, v0 and v1 used as local registers
		li      t0, 0x22
		mtc0    t0, CP0_ECC
		mtc0    $0, CP0_TAGHI
		mtc0    $0, CP0_TAGLO
		addu    v0, $0, a0
		addu    v1, a0, a2
		1:      slt     a3, v0, v1
		beq     a3, $0, 1f
		nop
		cache   Index_Store_Tag_S, 0x0(v0)
		cache   Index_Store_Tag_S, 0x1(v0)
		cache   Index_Store_Tag_S, 0x2(v0)
		cache   Index_Store_Tag_S, 0x3(v0)
		beq     $0, $0, 1b
		addiu   v0, v0, 0x20
		1:
		/*
scache_flush_4way:
addu    v0, $0, a0
addu    v1, a0, a2
1:      slt     a3, v0, v1
beq     a3, $0, 1f
nop
cache   Index_Writeback_Inv_S, 0x0(v0)
cache   Index_Writeback_Inv_S, 0x1(v0)
cache   Index_Writeback_Inv_S, 0x2(v0)
cache   Index_Writeback_Inv_S, 0x3(v0)
beq     $0, $0, 1b
addiu   v0, v0, 0x20
1:
		 */
scache_init_finish:
#	TTYDBG	("\r\nscache init ok\r\n")

#        ld      ra, 0(sp)
		jr      ra
		nop
		nop
#        daddiu  sp, sp, 8
		scache_init_panic:
		TTYDBG	("\r\nscache init panic\r\n")
		1:      b       1b
		nop
		END(scache_init)
		LEAF(scache_init_64)
		move	t7, ra

#lui     a0, 0x8000
#lui     a2, 0x0010      #4M/4way
		dli     a2, 0x00100000   #4M/4way
#lui     a2, 0x0002      #512k/4way
#lui     a2, 0x0004      #1M/4way
		scache_init_4way_64:
#a0=0x80000000, a2=scache_size
#a3, v0 and v1 used as local registers
		li      t0, 0x22
		mtc0    t0, CP0_ECC
		mtc0    $0, CP0_TAGHI
		mtc0    $0, CP0_TAGLO
		daddu    v0, $0, a0
		daddu    v1, a0, a2
		1:      //dslt     a3, v0, v1
		//beq     a3, $0, 1f
		beq     v0, v1, 1f
		nop
		cache   Index_Store_Tag_S, 0x0(v0)
		cache   Index_Store_Tag_S, 0x1(v0)
		cache   Index_Store_Tag_S, 0x2(v0)
		cache   Index_Store_Tag_S, 0x3(v0)
		beq     $0, $0, 1b
		daddiu   v0, v0, 0x20
		1:

		jr      ra
		nop

		1:      b       1b
		nop
		END(scache_init_64)
		LEAF(tlb_init)
		mtc0    $0, CP0_WIRED
		mtc0    $0, CP0_PAGEMASK
		tlb_flush_all:
		lui     a0, 0x8000
		addiu   a1, $0, 64
#a0=KSEG0,a1 = tlbsize, v0, v1, a3 used as local registers
		mtc0    $0, CP0_ENTRYLO0
		mtc0    $0, CP0_ENTRYLO1
		mfc0    v0, CP0_WIRED
		addu    v1, $0, a0
		1:      sltu    a3, v0, a1
		beq     a3, $0, 1f
		nop
		mtc0    v1, CP0_ENTRYHI
		mtc0    v0, CP0_INDEX
		tlbwi
		addiu   v1, v1, 0x2000
		beq     $0, $0, 1b
		addiu   v0, v0, 1
		1:
###tlb_init finish####
		tlbp
		jr      ra
		nop
		END(tlb_init)
###############################
		LEAF(hexserial64)
		move t7,ra
		move t6,a0
		dsrl a0,32
		bal hexserial
		nop
		move a0,t6
		bal hexserial
		nop
		jr t7
		END(hexserial64)

		LEAF(godson2_cache_init)
####part 2####
		cache_detect_4way:
		mfc0    t4, CP0_CONFIG
		andi    t5, t4, 0x0e00
		srl     t5, t5, 9
		andi    t6, t4, 0x01c0
		srl     t6, t6, 6
		addiu   t6, t6, 10      #4way
		addiu   t5, t5, 10      #4way
		addiu   t4, $0, 1
		sllv    t6, t4, t6
		sllv    t5, t4, t5
		addiu   t7, $0, 4
####part 3####
		lui     a0, 0x8000
#addu    a1, $0, t5
#addu    a2, $0, t6
		li      a1, (1<<14) #64k/4way
		li      a2, (1<<14)
		cache_init_d4way:
#a0=0x80000000, a1=icache_size, a2=dcache_size
#a3, v0 and v1 used as local registers
		mtc0    $0, CP0_TAGHI
		li      t0, 0x22
		mtc0    t0, CP0_ECC
		addu    v0, $0, a0
		addu    v1, a0, a2
		1:      slt     a3, v0, v1
		beq     a3, $0, 1f
		nop
		mtc0    $0, CP0_TAGLO
		cache   Index_Store_Tag_D, 0x0(v0)
		cache   Index_Store_Tag_D, 0x1(v0)
		cache   Index_Store_Tag_D, 0x2(v0)
		cache   Index_Store_Tag_D, 0x3(v0)
		beq     $0, $0, 1b
		addiu   v0, v0, 0x20
		1:
cache_flush_i4way:
		addu    v0, $0, a0
		addu    v1, a0, a1
		mtc0    $0, CP0_TAGLO
		mtc0    $0, CP0_TAGHI
		mtc0    $0, CP0_ECC
		1:      slt     a3, v0, v1
		beq     a3, $0, 1f
		nop
		cache   0x08, 0x0(v0)/*Index_Store_Tag_I*/
		cache   0x08, 0x1(v0)/*Index_Store_Tag_I*/
		cache   0x08, 0x2(v0)/*Index_Store_Tag_I*/
		cache   0x08, 0x3(v0)/*Index_Store_Tag_I*/
		beq     $0, $0, 1b
		addiu   v0, v0, 0x20
		1:
cache_init_finish:
		//TTYDBG	("\r\ncache init ok\r\n")

		jr      ra
		nop
		cache_init_panic:
		TTYDBG	("\r\ncache init panic\r\n")
		1:      b       1b
		nop
		.end	godson2_cache_init

		//lycheng
#if 0
		LEAF(nbmisc_read_index_mips)
		dli   t1, HT_CONFIG_ADDR
		or    t1, t1, a0
		sw    a1, NBMISC_INDEX(t1)
		lw    v0, 0x64(t1)
		j  ra
		nop
		END(nbmisc_read_index_mips)
		LEAF(nbmisc_write_index_mips)
		dli   t1, HT_CONFIG_ADDR
		or    t1, t1, a0
		or    t2, a1, 0x80
		sw    t2, 0x60(t1)
		sw    a2, 0x64(t1)
		j  ra
		nop
		END(nbmisc_write_index_mips)
		LEAF(post_code_mips)
		li t0, CPU_POST_PORT
		sb a0, 0x0(t0)
		j ra
		nop
		END(post_code_mips)
		LEAF(enable_rs780_dev8)
		move t6, ra
		li   a0,  0x0
		li   a1,  0x0
		bal    nbmisc_read_index_mips
		nop
		move   v1, v0
		li     t0,  0xffffffbf      // ~(1 << 6)
		and   t1, v1, t0
		li     t0,  0x40  // (1 << 6)
		or    v1, t1, t0
		beq    v1, v0, 1f
		nop
		//or  a1, a1, 0x80
		move a2,  v1
		bal   nbmisc_write_index_mips
		nop
		1:
		j  t6
		nop
		END(enable_rs780_dev8)
		LEAF(pci_read_config32_mips)
		dli t1, HT_CONFIG_ADDR
		or  t2, t1, a0
		or  t1, t2, a1
		lw  v0, 0x0(t1)
		j  ra
		nop
		END(pci_read_config32_mips)
		LEAF(pci_write_config32_mips)
		dli t1, HT_CONFIG_ADDR
		or  t2, t1, a0
		or  t1, t2, a1
		sw  a2, 0x0(t1)
		j  ra
		nop
		END(pci_write_config32_mips)
		LEAF(pci_read_config8_mips)
		dli t1, HT_CONFIG_ADDR
		or  t2, t1, a0
		or  t1, t2, a1
		lb  v0, 0x0(t1)
		j  ra
		nop
		END(pci_read_config8_mips)
		LEAF(pci_write_config8_mips)
		dli t1, HT_CONFIG_ADDR
		or  t2, t1, a0
		or  t1, t2, a1
		sb  a2, 0x0(t1)
		j  ra
		nop
		END(pci_write_config8_mips)

		LEAF(pci_read_config8)
		dli t1, HT_CONFIG_ADDR
		or  t2, t1, a0
		or  t1, t2, a1
		lb  v0, 0x48(t1)
		j  ra
		nop
		END(pci_read_config8)
		LEAF(pci_write_config8)
		dli t1, HT_CONFIG_ADDR
		or  t2, t1, a0
		or  t1, t2, a1
		sb  a2, 0x48(t1)
		j  ra
		nop
		END(pci_write_config8)
		LEAF(enable_lpcio_dev8)
		move t6, ra
		li   a0,20
		li	 a1,3
		sll  a0,11
		sll  a1,8
		bal    pci_read_config8
		nop
		move   v1, v0
		li     t0,  0x3
		or     t1, v1, t0
		move   a2,  t1
		bal   pci_write_config8
		nop
		j  t6
		nop
		END(enable_lpcio_dev8)
#endif

    .ent	slave_main
slave_main:
#if 1
    mfc0	t0, CP0_STATUS
    li      t1, 0x00e0  //set {UX,SX,KX} to 3'b111
    or      t0, t0, t1
    mtc0    t0, CP0_STATUS

    mfc0    t0, CP0_STATUS
    lui     t1, 0x40    //set bev to 1'b1
    or      t0, t0, t1
    mtc0    t0, CP0_STATUS

    mtc0    zero, CP0_CAUSE
#endif

    bal     tlb_init
    nop

    bal     godson2_cache_init
    nop

#if 0
//the dead loop core will cause exception no matter before or after the tlb_init!
//and the id of slave core doesn't matter
//why???
    .set mips64
    mfc0    t2, $15, 1
    andi    t2, 0x3ff
    .set mips3
    dli     t0, 0x2
    bne     t2, t0, 2f
    nop
1:
    b       1b
    nop
2:
#endif

//wait core0 init done
    dli     t0, CORE0_BUF0 #buf of cpu0
    li      a1, SYSTEM_INIT_OK
1:
#if 1
    li      a0, 0x10000
2:
    addiu   a0, -1
    bnez    a0, 2b
    nop
#endif
    lw      a0, 0x0(t0)
    bne     a1, a0, 1b
    nop

#if 1
#if 1
/***********************
    Important!!!
    this code CAN NOT be removed.
***********************/
    mfc0	t0, CP0_CONFIG
    ori	    t0, t0, 7
    xori	t0, t0, 4
    mtc0	t0, CP0_CONFIG
#endif

//jump to 0x9fcxxxxx
    lui     t0, 0xdfff
    ori     t0, t0, 0xffff
    bal     1f
    nop
1:
    and     ra, ra, t0
    addiu   ra, ra, 16
    jr      ra
    nop

    sync
    nop
    nop
    nop
    nop
    ## enable kseg0 cachablilty####
    mfc0    t0, CP0_CONFIG
    lui     t1, 0xffff
    ori     t1, t1, 0xfff8
    and     t0, t0, t1
    ori     t0, t0, 0x3
    mtc0    t0, CP0_CONFIG
    ################################
#endif

    .set mips64
    mfc0    t2, $15, 1
    andi    t2, 0x3ff
    .set mips3

    dli     t0, 0x900000003ff01000 
    andi    t3, t2, 0x3  #local core id
    sll     t3, 8
    or      t0, t0, t3

    andi    t4, t2, 0xc  #node id
    dsll    t4, 42
    or      t0, t0, t4

waitforinit:   
    li      a0, 0x10000
idle1000:    
    addiu   a0, -1
    bnez    a0, idle1000
    nop

    lw      v0, FN_OFF(t0)
    beqz    v0, waitforinit
    nop

    dli     t1, 0xffffffff00000000 
    or      v0, t1

    dli     t1, 0x9800000000000000 
    ld      sp, SP_OFF(t0)
    or      sp, t1
    ld      gp, GP_OFF(t0)
    or      gp, t1
    ld      a1, A1_OFF(t0)

    jalr    v0  #byebye 
    nop
#######
1:
    b   1b
    nop
    .end	slave_main


    .global watchdog_enable
    .ent    watchdog_enable
    .set    noreorder
    .set    mips3
watchdog_enable:
    WatchDog_Enable
    jr		ra
    nop
    .end watchdog_enable

#######################################
#include "ddr_dir/ddr_config.S"
#ifdef ARB_LEVEL
#include "ddr_dir/ARB_level_new.S"
#endif
#ifdef  DEBUG_DDR
#include "ddr_dir/Test_Mem.S"
#endif

    .rdata
    .global ddr2_reg_data
    .global ddr3_reg_data

    .align  5
#include "loongson3A3_ddr_param.S"

#ifdef  ARB_LEVEL
    .text
    .global c0_mc0_level_info 
    .global c0_mc1_level_info 

#include "ddr_dir/loongson3A3_ddr_param.lvled.S"
#else
#ifdef FIX_DDR_PARAM
#include "loongson3A3_ddr_param.fix.S"
#endif
#endif

    .text
    .global  nvram_offs
    .align 12
nvram_offs:
    .dword 0x0
    .align 12
